﻿using System;
using System.Reflection;
using System.Collections.Generic;

namespace FrameWork.Core.Utils
{
    /// <summary>
    /// 反射处理类
    /// </summary>
    public static class ReflectionHelper
    {

        private static readonly Dictionary<Type, PropertyInfo[]> DicPropertys = new Dictionary<Type, PropertyInfo[]>();
        /// <summary>
        /// 对比列的值是否改变
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="column"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsChangeValue<T>(T t, string column, object value)
        {
            PropertyInfo[] pros = t.GetType().GetProperties();
            foreach (PropertyInfo pi in pros)
                if (pi.Name == column)
                    return pi.GetValue(t, null) != value;
            return false;
        }
        /// <summary>
        /// 从map中取值分配给属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="map"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public static void SetingValue<T>(Dictionary<string, object> map, ref T t)
        {
            PropertyInfo[] PropertyInfos = null;
            if (!DicPropertys.TryGetValue(typeof(T), out PropertyInfo[] outPropertyInfos))
            { 
                var p =  typeof(T).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
                DicPropertys[typeof(T)] = p;
                PropertyInfos = p;
            }
            else
                PropertyInfos = outPropertyInfos;

            foreach (PropertyInfo pi in PropertyInfos)
            {
                if (map.ContainsKey(pi.Name))
                {
                    switch (pi.PropertyType.FullName)
                    {
                        case "System.String":
                            pi.SetValue(t, map[pi.Name].ToString());
                            break;
                        case "System.Int32":
                            int n = 0;
                            if (int.TryParse(map[pi.Name].ToString(), out n))
                            {
                                pi.SetValue(t, n);
                            }
                            break;
                        case "System.DateTime":
                            DateTime now = DateTime.MinValue;
                            if (DateTime.TryParse(map[pi.Name].ToString(), out now))
                            {
                                pi.SetValue(t, now);
                            }
                            break;
                        case "System.Boolean":
                            bool boo = false;
                            if (bool.TryParse(map[pi.Name].ToString(), out boo))
                            {
                                pi.SetValue(t, boo);
                            }
                            break;
                        case "System.Decimal":
                            decimal dec = 0;
                            if (decimal.TryParse(map[pi.Name].ToString(), out dec))
                            {
                                pi.SetValue(t, dec);
                            }
                            break;
                        case "System.Double":
                            double dou = 0;
                            if (double.TryParse(map[pi.Name].ToString(), out dou))
                            {
                                pi.SetValue(t, dou);
                            }
                            break;
                        case "Enum":
                            var enumValue = System.Enum.Parse(pi.PropertyType.GetGenericArguments()[0], map[pi.Name].ToString());
                            pi.SetValue(t, enumValue);
                            break;
                        default:
                            pi.SetValue(t, map[pi.Name]);
                            break;
                    }
                }
            }
        }
    }
}
